//
//  TableVM.swift
//  CooperSwift_Example
//
//  Created by 计海峰 on 2021/5/24.
//  Copyright © 2021 CocoaPods. All rights reserved.
//

import Foundation
import RxDataSources
import RxSwift

private struct AssociateKeys {
    static var sectionKey: Void?
    static var sectionSubjectKey: Void?
    static var serviceSubjectKey: Void?
    static var targetBlockKey: Void?
    static var serviceBlockKey: Void?
    static var dataSourceKey: Void?
}

// MARK: - data enable
protocol TableViewModelProtocol : UITableViewDelegate, BindKeyProtocol { }

// MARK: - sections
extension TableViewModelProtocol {
    
    typealias SectionM = SectionModel<Any, TableCellConfigProtocol>
  
    // MARK: -  table 对应 sections BehaviorSubject
    var sectionsSubject: BehaviorSubject<[SectionM]> {
        get {
            return associatedObject(forKey: &AssociateKeys.sectionSubjectKey, default: BehaviorSubject<[SectionM]>(value: self.sections), ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.sectionSubjectKey, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
  
    // MARK: -  table 对应 sections
    var sections: [SectionM]
    {
        get {
            return associatedObject(forKey: &AssociateKeys.sectionKey, default: [SectionM](), ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.sectionKey, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            self.sectionsSubject.onNext(newValue)
        }
    }

   // MARK: -  第一个section 没有的话 默认创建
    
   @discardableResult
   func firstSection() -> SectionM {
    if let section = self.sections.first {
           return section
       }
    self.sections += [SectionModel<Any, TableCellConfigProtocol>(model: "Section0", items: [])]
    return self.sections.first!
   }
    
    func updateFirstSectionItems(_ items: [TableCellConfigProtocol]) -> Void {
        var sectionOne = firstSection()
        sectionOne.items = items
        self.sections[0] = sectionOne
    }
    
    func addFirstSectionItems(_ items: [TableCellConfigProtocol]) -> Void {
        var sectionOne = firstSection()
        sectionOne.items += items
        self.sections[0] = sectionOne
    }
    
}


// MARK: - rx data s,ource
extension TableViewModelProtocol {
    
    // MARK: - dataSource 初始化
    private var dataSource : RxTableViewSectionedReloadDataSource<SectionM>? {
        get {
            return objc_getAssociatedObject(self, &AssociateKeys.dataSourceKey) as? RxTableViewSectionedReloadDataSource<SectionM>
        }
        set {
            objc_setAssociatedObject(self, &AssociateKeys.dataSourceKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    @discardableResult
    func configDataSource() -> RxTableViewSectionedReloadDataSource<SectionM> {
        if let ds = dataSource {
            return ds
        }
        dataSource = RxTableViewSectionedReloadDataSource<SectionM>(
            configureCell: { dataSource, tv, indexPath, item in
                
                let cell = tv.dequeueReusableCell(indexPath: indexPath, cls: item.cellCls())
                
                // 绑定数据
                cell.bindTo(item)
                // cell 默认配置
                cell.selectionStyle = .none
                // 背景色
                if let bgColor = item.bgColor() {
                    cell.backgroundColor = bgColor
                }
                // 行高
                if let cellHeight = item.cellHeight() {
                    cell.isHidden = cellHeight == 0
                }
                
                return cell
            }
        )
        return dataSource!
    }
    
}


// MARK: - service
extension TableViewModelProtocol {
    
    typealias TargetBlock = (_ service: TableViewModelFromTargetServiceEnum) -> Any?
    
    // MARK: -  table 对应 sections BehaviorSubject
    var serviceSubject: BehaviorSubject<Any> {
        get {
            return associatedObject(forKey: &AssociateKeys.serviceSubjectKey, default: BehaviorSubject(value: ""), ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.serviceSubjectKey, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    private var serviceBlock: TargetBlock? {
        get {
            return (objc_getAssociatedObject(self, &AssociateKeys.serviceBlockKey) as? Self.TargetBlock)
        }
        set {
            objc_setAssociatedObject(self, &AssociateKeys.serviceBlockKey, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC)
        }
    }
      
    func configServicBlock(block: @escaping TargetBlock) -> Void {
        serviceBlock = block
    }
    
    func currentTV() -> UITableView? {
        guard let block = serviceBlock else { return nil}
        let tv = block(.table) as! UITableView
        return tv
    }
    
    
}

extension TableViewModelProtocol {
    
    func test() {
        
    }
    
}


class TableViewModelSeviceHolder: ServiceHolder {
    
}
